home *** CD-ROM | disk | FTP | other *** search
/ Racing Games (Spidla) / zavodni.iso / Fun Racing / src / FRCar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2003-06-19  |  20.7 KB  |  855 lines

  1.  
  2. #include "FRCar.h"
  3. #include "FRPowerUp.h"
  4. #include "FRTrackObjects.h"
  5.  
  6. TERTTIImplementation(FRCar, TEEngineObject);
  7.  
  8. bool FRCar::ms_bPowerUpsEnabled = true;
  9. bool FRCar::ms_bTyreDecals = true;
  10. bool FRCar::ms_bSmoke = true;
  11.  
  12. FRCar::FRCar()
  13. {
  14.     TESoundManager* pSound = TESoundManager::GetSoundManager();
  15.     TETextureManager* pTex = TETextureManager::GetTextureManager();
  16.     TEString Pak = "EngineSFX";
  17.     TEString Name = "corona01";
  18.  
  19.     m_pFrontLight = pTex->GetTexture(Name, Pak, false, 1, true);
  20.     Name = "corona02";
  21.     m_pBackLight = pTex->GetTexture(Name, Pak, false, 1, true);
  22.  
  23.     m_ulAINode = m_ulTrackNode = m_ulLap = 0;
  24.     m_ulLastAINodeChange = TETimer::GetTimer()->GetTime();
  25.     m_bAIUsesHorn = false;
  26.     m_Type = AI;
  27.     m_State = WAITING;
  28.     m_Visibility = NORMAL;
  29.  
  30.     m_fElasticity = 0.7f;
  31.     m_fFrictionFactor = 1.0f;
  32.  
  33.     m_bShadow = true;
  34.     m_pMotor = NULL;
  35.     m_pBraking = NULL;
  36.     m_pHorn = NULL;
  37.  
  38.     m_fMaxRPM = 0.0f;
  39.     m_fRotFactor = 0.0f;
  40.  
  41.     m_ulNumGears = 0;
  42.     m_aGears = NULL;
  43.     m_fCurrentRPM = 0;
  44.     m_lCurrentGear = NEUTRAL_GEAR;
  45.  
  46.     m_fPedal = 0.0f;
  47.     m_fSteeringWheel = 0.0f;
  48.     m_bHandbrake = false;
  49.  
  50.     m_fFrontAxis = 0.0f;
  51.     m_fRearAxis = 0.0f;
  52.  
  53.     m_bBraking = false;
  54.  
  55.     m_bTransparency = false;
  56.  
  57.     m_fWheelWidth = 0.0f;
  58.     m_fWheelMov = 0.0f;
  59.  
  60.     m_fDecalLengthLeft = 0;
  61.     m_fDecalLengthRight = 0;
  62.     m_pDecalLeft = NULL;
  63.     m_pDecalRight = NULL;
  64.  
  65.     m_bClip = true;
  66.     m_bDynamicLights = false;
  67.     m_bStatic = false;
  68.     m_bApplyGravity = false;
  69.     m_fBrakeEfficiency = 1.0f;
  70.  
  71.     m_usNumExhaust = 0;
  72.  
  73.     m_lPowerUp = -1;
  74.     m_ulPowerUpEndTime = 0;
  75.     m_lPowerUpInfluence = -1;
  76.  
  77.     Name = "pickup.ogg";
  78.     m_pPickup = pSound->GetSound(Name);
  79.     Name = "fire.ogg";
  80.     m_pFire = pSound->GetSound(Name);
  81. }
  82.  
  83. FRCar::~FRCar()
  84. {
  85.     SafeDelete(m_pFrontLight);
  86.     SafeDelete(m_pBackLight);
  87.  
  88.     SafeDelete(m_pPickup);
  89.     SafeDelete(m_pFire);
  90.  
  91.     SafeDelete(m_pMotor);
  92.     SafeDelete(m_pBraking);
  93.     SafeDelete(m_pHorn);
  94.     SafeDeleteA(m_aGears);
  95. }
  96.  
  97. void FRCar::Horn(void)
  98. {
  99.     if(m_pHorn != NULL && !m_pHorn->IsPlaying())
  100.         m_pHorn->Play3D(m_Center, m_Velocity, 0, 1.0f);
  101. }
  102.  
  103. void FRCar::SetPedal(Float fPedal)
  104. {
  105.     if(fPedal > 1.0f)
  106.         fPedal = 1.0f;
  107.     if(fPedal < -1.0f)
  108.         fPedal = -1.0f;
  109.  
  110.     m_fPedal = fPedal;
  111. }
  112.  
  113. void FRCar::SetSteeringWheel(Float fWheel)
  114. {
  115.     if(fWheel > 1.0f)
  116.         fWheel = 1.0f;
  117.     if(fWheel < -1.0f)
  118.         fWheel = -1.0f;
  119.  
  120.     m_fSteeringWheel = fWheel;
  121. }
  122.  
  123. Float FRCar::GetSpeedKMH(void)
  124. {
  125.     return TEAbs(m_aGears[m_lCurrentGear].fRPMTrans * m_fCurrentRPM / m_fMaxRPM * 0.36f);
  126. //    return m_Velocity.GetLength() * 0.36f;
  127. }
  128.  
  129. void FRCar::SetPowerUp(UInt32 lPowerUp)
  130. {
  131.     if(!ms_bPowerUpsEnabled || m_lPowerUp != -1)
  132.         return;
  133.  
  134.     if(m_pPickup != NULL)
  135.         m_pPickup->Play3D(m_Center, m_Velocity, 0, 1.5f);
  136.  
  137.     m_lPowerUp = lPowerUp;
  138. }
  139.  
  140. void FRCar::EnablePowerUp(void)
  141. {
  142.     if(!ms_bPowerUpsEnabled || m_lPowerUp == -1)
  143.         return;
  144.  
  145.     TEVector Pos;
  146.     TEEngineObject* pObj;
  147.  
  148.     if(m_lPowerUp == POWERUP_N2O && m_lPowerUpInfluence != POWERUP_N2O)
  149.     {
  150.         m_ulPowerUpEndTime = TETimer::GetTimer()->GetTime() + 4000;
  151.  
  152.         for(UInt32 ulCount = 1; ulCount < m_ulNumGears; ulCount++)
  153.         {
  154.             m_aGears[ulCount].fRPMChange *= 4.0f;
  155.             m_aGears[ulCount].fRPMTrans += 250.0f;
  156.         }
  157.  
  158.         m_lPowerUpInfluence = POWERUP_N2O;
  159.     }
  160.     else if(m_lPowerUp == POWERUP_ROCKET)
  161.     {
  162.         Pos = m_pBoundingVolume->GetCenter() + m_Forward * (m_CarSize.m_fZ * 0.51f + 8.0f);
  163.         pObj = new FREMPRocket(Pos, m_Forward, m_Rotation);
  164.         TEEngine::GetEngine()->AddObjectToWorld(pObj);
  165.     }
  166.     else if(m_lPowerUp == POWERUP_MINE)
  167.     {
  168.         Pos = m_pBoundingVolume->GetCenter() - m_Forward * (m_CarSize.m_fZ * 0.51f + 5.0f);
  169.         pObj = new FREMPMine(Pos);
  170.         TEEngine::GetEngine()->AddObjectToWorld(pObj);
  171.     }
  172.     else if(m_lPowerUp == POWERUP_OIL)
  173.     {
  174.         Pos = m_pBoundingVolume->GetCenter() - m_Forward * (m_CarSize.m_fZ * 0.51f + 15.0f);
  175.         pObj = new FROilPuddle(Pos);
  176.         TEEngine::GetEngine()->AddObjectToWorld(pObj);
  177.     }
  178.  
  179.     if(m_pFire != NULL)
  180.         m_pFire->Play3D(m_Center, m_Velocity, 0, 1.5f);
  181.  
  182.     m_lPowerUp = -1;
  183. }
  184.  
  185. void FRCar::EMPHit(void)
  186. {
  187.     if(m_lPowerUpInfluence == POWERUP_N2O)
  188.     {
  189.         for(UInt32 ulCount = 1; ulCount < m_ulNumGears; ulCount++)
  190.         {
  191.             m_aGears[ulCount].fRPMChange *= 0.25f;
  192.             m_aGears[ulCount].fRPMTrans -= 250.0f;
  193.         }
  194.     }
  195.  
  196.     m_ulPowerUpEndTime = TETimer::GetTimer()->GetTime() + 3000;
  197.     m_lPowerUpInfluence = POWERUP_MINE;
  198. }
  199.  
  200. void FRCar::OilHit(void)
  201. {
  202.     if(m_lPowerUpInfluence == POWERUP_N2O)
  203.     {
  204.         for(UInt32 ulCount = 1; ulCount < m_ulNumGears; ulCount++)
  205.         {
  206.             m_aGears[ulCount].fRPMChange *= 0.25f;
  207.             m_aGears[ulCount].fRPMTrans -= 250.0f;
  208.         }
  209.     }
  210.  
  211.     m_ulPowerUpEndTime = TETimer::GetTimer()->GetTime() + 1000;
  212.     m_lPowerUpInfluence = POWERUP_OIL;
  213. }
  214.  
  215. void FRCar::Render(TERenderer* pRender, TECamera* pCam)
  216. {
  217.     TEVector Tmp, Center, Cam;
  218.     Float fScale, fDist, fMaxCorona;
  219.  
  220.     if(m_Visibility == INVISIBLE)
  221.         return;
  222.     else if(m_Visibility == BLINKING)
  223.     {
  224.         UInt32 ulTmp, ulTime = TETimer::GetTimer()->GetElapsedTime(m_ulLastReset);
  225.  
  226.         if(ulTime < 1000)
  227.         {
  228.             ulTmp = ulTime % 250;
  229.             
  230.             m_bClip = false;
  231.  
  232.             if(ulTmp > 75 + ulTime / 25)
  233.                 return;
  234.         }
  235.         else
  236.         {
  237.             m_bClip = true;
  238.             m_Visibility = NORMAL;
  239.         }
  240.     }
  241.  
  242.     TEEngineObject::Render(pRender, pCam);
  243.  
  244.     fMaxCorona = TEEngine::GetEngine()->GetMaxCoronaDistance();
  245.     Cam = pCam->GetPosition();
  246.     Center = m_pBoundingVolume->GetCenter();
  247.     fDist = (Center - Cam).GetLength();
  248.  
  249.     if(fDist < fMaxCorona)
  250.     {
  251.         if(fDist > fMaxCorona/4.0f)
  252.             fScale = MAX_LIGHT_SIZE;
  253.         else
  254.             fScale = fDist * TEEngine::GetEngine()->GetCoronaFactor();
  255.  
  256.         if(fScale < MIN_LIGHT_SIZE)
  257.             fScale = MIN_LIGHT_SIZE;
  258.         else if(fScale > MAX_LIGHT_SIZE)
  259.             fScale = MAX_LIGHT_SIZE;
  260.  
  261.         pRender->SetZBufferState(false);
  262.         pRender->EnableBlending();
  263.         pRender->SetBlendingState(BLEND_SRC_ALPHA, BLEND_ONE);
  264.  
  265.         pRender->SetAmbient(255, 255, 255, 192);
  266.         
  267.         Tmp = Center + m_aLightPos[0].m_fX * m_Right + m_aLightPos[0].m_fY * m_Up + m_aLightPos[0].m_fZ * m_Forward;
  268.         pRender->RenderParticle(Tmp, fScale, fScale, m_pFrontLight);
  269.  
  270.         Tmp = Center + m_aLightPos[1].m_fX * m_Right + m_aLightPos[1].m_fY * m_Up + m_aLightPos[1].m_fZ * m_Forward;
  271.         pRender->RenderParticle(Tmp, fScale, fScale, m_pFrontLight);
  272.  
  273.         if(m_fPedal < 0)
  274.         {
  275.             if(m_lCurrentGear == REVERSE_GEAR)
  276.                 pRender->SetAmbient(255, 255, 255, 255);
  277.             else pRender->SetAmbient(255, 0, 0, 255);
  278.             
  279.             Tmp = Center + m_aLightPos[2].m_fX * m_Right + m_aLightPos[2].m_fY * m_Up + m_aLightPos[2].m_fZ * m_Forward;
  280.             pRender->RenderParticle(Tmp, fScale, fScale, m_pBackLight);
  281.  
  282.             Tmp = Center + m_aLightPos[3].m_fX * m_Right + m_aLightPos[3].m_fY * m_Up + m_aLightPos[3].m_fZ * m_Forward;
  283.             pRender->RenderParticle(Tmp, fScale, fScale, m_pBackLight);
  284.         }
  285.  
  286.         pRender->SetZBufferState(true);
  287.         pRender->DisableBlending();
  288.     }
  289.  
  290. }
  291.  
  292. void FRCar::RenderShadow(TERenderer* pRender, TECamera* pCam, TELight* pLights, 
  293.         TEShadowMethod DefaultMethod, bool bMoreThanOneShadow)
  294. {
  295.     // optimized shadow routines
  296.  
  297.     if(m_Visibility == INVISIBLE)
  298.         return;
  299.  
  300.     if(DefaultMethod == SHADOW_NONE)
  301.         return;
  302.     else if(DefaultMethod == SHADOW_FAKE)
  303.     {
  304.         TEVector Center = m_pBoundingVolume->GetCenter();
  305.         pRender->SetAmbient(192, 192, 192);
  306.         TEEngine::GetEngine()->RenderFakeShadow(m_Forward, Center,
  307.             m_CarSize.m_fX, m_CarSize.m_fZ);
  308.     }
  309.     else
  310.     {
  311.         TEEngine* pEngine = TEEngine::GetEngine();
  312.         TELight *pCurrentLight;
  313.         TEVector LightPos;
  314.  
  315.         pCurrentLight = GetClosestLight(pLights, LightPos);
  316.  
  317.         if(DefaultMethod == SHADOW_PROJECTED)
  318.         {
  319.             TEPlane Plane;
  320.  
  321.             Plane.m_Normal = TEVector(0.0f, 1.0f, 0.0f);
  322.             Plane.m_D = 0;
  323.             
  324.             pRender->SetAmbient(0, 0, 0);
  325.             
  326.             m_pModelRef->RenderProjectedShadow(pRender, m_Center, m_Rotation,
  327.                 LightPos, Plane);
  328.         }
  329.         else if(DefaultMethod == SHADOW_PROJECTED_STENCIL)
  330.         {
  331.             TEVector Dir = m_Center - LightPos;
  332.             
  333.             if(!pEngine->GetTerrain()->Clips(LightPos, Dir))
  334.             {
  335.                 TEPlane Plane;
  336.  
  337.                 Plane.m_Normal = TEVector(0.0f, 1.0f, 0.0f);
  338.                 Plane.m_D = 0;
  339.                 
  340.                 pRender->ClearStencilBuffer();
  341.                 pRender->EnableStencilBuffer();
  342.                 pRender->EnableBlending();
  343.                 pRender->SetBlendingState(BLEND_SRC_ALPHA,
  344.                     BLEND_ONE_MINUS_SRC_ALPHA);
  345.                 
  346.                 pRender->SetStencilComp(STENCIL_COMP_EQUAL, 0, 0xFFFFFFFF);
  347.                 pRender->SetStencilOp(STENCIL_OP_KEEP, STENCIL_OP_KEEP,
  348.                     STENCIL_OP_INCREASE); 
  349.                 
  350.                 pRender->SetAmbient(0, 0, 0, (UChar) (255 - ((m_afLight[0] + m_afLight[1] + m_afLight[2]) / 3.0f) * 128));
  351.                 
  352.                 m_pModelRef->RenderProjectedShadow(pRender, m_Center, m_Rotation,
  353.                 LightPos, Plane);
  354.  
  355.                 pRender->DisableBlending();
  356.                 pRender->DisableStencilBuffer();            
  357.             }
  358.         }
  359.         else if(DefaultMethod == SHADOW_STENCIL_VOLUME)
  360.         {
  361.             TEVector Dir = m_Center - LightPos;
  362.             
  363.             if(!pEngine->GetTerrain()->Clips(LightPos, Dir))
  364.             {
  365.                 pRender->SetAmbient(0, 0, 0, (UChar) (255 - ((m_afLight[0] + m_afLight[1] + m_afLight[2]) / 3.0f) * 128));
  366.                 
  367.                 m_pModelRef->RenderStencilShadow(pRender, pCam, m_Center,
  368.                     m_Rotation, LightPos);
  369.             }
  370.         }
  371.     }
  372. }
  373.  
  374. void FRCar::Animate(UInt32 ulDeltaT, TEEngine* pEngine)
  375. {
  376.     Float fScale;
  377.     TEVector Min, Max;    
  378.  
  379.     if(m_State == WAITING || (m_ulTrackNode < 2 && m_State >= FINISHED1ST && m_State <= FINISHED4TH) ||
  380.         ( (m_State == KO || m_State == DESTROYED) && GetSpeedKMH() < 5) )
  381.     {
  382.         m_pModelRef->SetTimeScale(0.0f);
  383.         return;
  384.     }
  385.  
  386.     m_bBraking = false;
  387.  
  388.     if(m_lCurrentGear == NEUTRAL_GEAR)
  389.     {
  390.         fScale = 0;
  391.     }
  392.     else
  393.     {        
  394.         fScale = m_Velocity.GetLength() / 25.0f;
  395.  
  396.         if(fScale > 10.0f)
  397.             fScale = 10.0f;
  398.     }
  399.     
  400.  
  401.     if(m_fSteeringWheel == 0 && m_pModelRef->GetCurrentAnimation() != 0)
  402.         m_pModelRef->SetAnimation(0);
  403.     else if(m_fSteeringWheel < 0.0f && m_pModelRef->GetCurrentAnimation() != 1)
  404.         m_pModelRef->SetAnimation(1);
  405.     else if(m_fSteeringWheel > 0.0f && m_pModelRef->GetCurrentAnimation() != 2)
  406.         m_pModelRef->SetAnimation(2);
  407.  
  408.     m_pModelRef->SetTimeScale(fScale);
  409.     
  410.     if(m_lCurrentGear == REVERSE_GEAR)
  411.         m_pModelRef->SetReverseAnimation(true);
  412.     else m_pModelRef->SetReverseAnimation(false);
  413.  
  414.     if(m_fSteeringWheel != 0 && m_lPowerUpInfluence != POWERUP_OIL && m_Visibility != BLINKING)
  415.     {
  416.         TEAABoundingBox BBox;
  417.         TEVector Min, Max;
  418.         TEOBoundingBox* pBox = (TEOBoundingBox*) m_pBoundingVolume;
  419.         Float fSpeed = GetSpeedKMH();
  420.         Float fTime = ulDeltaT / 1000.0f;
  421.         
  422.         if(fSpeed >= 50.0f)
  423.         {
  424.             if(m_lCurrentGear != REVERSE_GEAR)
  425.                 m_Rotation.m_fY += m_fSteeringWheel * m_fRotFactor * fTime;
  426.             else m_Rotation.m_fY -= m_fSteeringWheel * m_fRotFactor * fTime;
  427.             
  428.         }
  429.         else
  430.         {
  431.             if(m_lCurrentGear != REVERSE_GEAR)
  432.                 m_Rotation.m_fY += m_fSteeringWheel * m_fRotFactor * fTime * fSpeed * 0.02f;
  433.             else m_Rotation.m_fY -= m_fSteeringWheel * m_fRotFactor * fTime * fSpeed * 0.02f;
  434.         }
  435.         
  436.         while(m_Rotation.m_fY >= 360.0f)
  437.             m_Rotation.m_fY -= 360.0f;
  438.         while(m_Rotation.m_fY < 0.0f)
  439.             m_Rotation.m_fY += 360.0f;
  440.         
  441.         BBox = m_pModelRef->GetModelBBox();
  442.         BBox.GetData(Min, Max);
  443.         pBox->SetData(m_Center, Min, Max, m_Rotation);
  444.         UpdateVectors();
  445.     }
  446.  
  447.     UpdateEngine(ulDeltaT, pEngine);
  448.  
  449.     if(m_ulPowerUpEndTime != 0 && TETimer::GetTimer()->GetTime() > m_ulPowerUpEndTime)
  450.     {
  451.         m_ulPowerUpEndTime = 0;
  452.  
  453.         if(m_lPowerUpInfluence == POWERUP_N2O)
  454.         {
  455.             for(UInt32 ulCount = 1; ulCount < m_ulNumGears; ulCount++)
  456.             {
  457.                 m_aGears[ulCount].fRPMChange *= 0.25f;
  458.                 m_aGears[ulCount].fRPMTrans -= 250.0f;
  459.             }
  460.         }
  461.  
  462.         m_lPowerUpInfluence = -1;
  463.     }
  464. }
  465.  
  466. void FRCar::Update(UInt32 ulDeltaT, TEEngine* pEngine)
  467. {
  468.     m_Acceleration.m_fY = m_Velocity.m_fY = 0;
  469.     
  470.     if(m_Center.m_fY != m_fDeltaY)
  471.     {
  472.         Float fDelta = m_fDeltaY - m_Center.m_fY;
  473.         TEVector Tmp = m_pBoundingVolume->GetCenter();
  474.         Tmp.m_fY += fDelta;
  475.         m_pBoundingVolume->SetCenter(Tmp);
  476.         m_Center.m_fY = m_fDeltaY;
  477.     }
  478.  
  479.     TEEngineObject::Update(ulDeltaT, pEngine);
  480.  
  481.     UInt16 usCount;
  482.     TEVector Center = m_pBoundingVolume->GetCenter();
  483.     Float fSpeed;
  484.  
  485.     fSpeed = m_Velocity.GetLength();
  486.  
  487.     UpdateVectors();
  488.  
  489.     if(((m_fPedal < 0 && m_lCurrentGear != REVERSE_GEAR) || m_bHandbrake ||
  490.         m_lPowerUpInfluence == POWERUP_OIL) &&    fSpeed > MIN_DECAL_SPEED)
  491.     {
  492.         if(m_pBraking != NULL && !m_pBraking->IsPlaying())
  493.             m_pBraking->Play3D(m_Center, m_Velocity, 0, 1.0f);
  494.  
  495.         if(ms_bTyreDecals)
  496.             CreateTyreDecals(ulDeltaT, pEngine);
  497.     }
  498.     else m_pDecalLeft = m_pDecalRight = NULL;
  499.  
  500.     if(ms_bSmoke)
  501.     {
  502.         for(usCount = 0; usCount < m_usNumExhaust; usCount++)
  503.         {
  504.             TEVector Tmp = Center + m_aExhaustPos[usCount].m_fX * m_Right +
  505.                 m_aExhaustPos[usCount].m_fY * m_Up + m_aExhaustPos[usCount].m_fZ * m_Forward;
  506.             
  507.             m_aExhaust[usCount]->MoveToPosition(Tmp);
  508.         }
  509.     }
  510.  
  511.     if(m_pMotor != NULL)
  512.         m_pMotor->UpdateProperties(m_Center, m_Velocity);
  513.     if(m_pBraking != NULL && m_pBraking->IsPlaying())
  514.         m_pBraking->UpdateProperties(m_Center, m_Velocity);
  515.     if(m_pHorn != NULL && m_pHorn->IsPlaying())
  516.         m_pHorn->UpdateProperties(m_Center, m_Velocity);
  517.  
  518.     if(m_pPickup != NULL && m_pPickup->IsPlaying())
  519.         m_pPickup->UpdateProperties(m_Center, m_Velocity);
  520.     if(m_pFire != NULL && m_pFire->IsPlaying())
  521.         m_pFire->UpdateProperties(m_Center, m_Velocity);
  522. }
  523.  
  524. bool FRCar::Influence(UInt32 ulDeltaT, TEEngineObject* pObject)
  525. {
  526.     bool bCar = TEIsDerivedFromClass(FRCar, pObject);
  527.  
  528.     if(bCar && (m_Visibility == BLINKING || ((FRCar*)pObject)->m_Visibility == BLINKING))
  529.         return false;
  530.     
  531.     return TEEngineObject::Influence(ulDeltaT, pObject);
  532. }
  533.  
  534. void FRCar::OnClip(TEEngineObject* pInfluencer)
  535. {
  536.     if(TEIsDerivedFromClass(FRCar, pInfluencer) &&
  537.         m_Type == AI && m_bAIUsesHorn && !m_pHorn->IsPlaying())
  538.     {
  539.         TEVector Dir = pInfluencer->GetCenter() - m_Center;
  540.         Dir.Normalize();
  541.  
  542.         if(Dir.DotProduct(m_Forward) >= 0.5f)
  543.             Horn();
  544.     }
  545.     else if(TEIsTypeOfClass(TEBSPTerrain, pInfluencer) ||
  546.         TEIsTypeOfClass(FRBarrier, pInfluencer))
  547.     {
  548.         if(m_lPowerUpInfluence == POWERUP_N2O)
  549.         {
  550.             for(UInt32 ulCount = 1; ulCount < m_ulNumGears; ulCount++)
  551.             {
  552.                 m_aGears[ulCount].fRPMChange *= 0.25f;
  553.                 m_aGears[ulCount].fRPMTrans -= 250.0f;
  554.             }
  555.  
  556.             m_fCurrentRPM = 1000.0f;
  557.             m_lCurrentGear = NEUTRAL_GEAR;
  558.             m_Velocity = m_Acceleration = TEVector(0.0f, 0.0f, 0.0f);
  559.             m_lPowerUpInfluence = -1;
  560.             m_ulPowerUpEndTime = 0;
  561.         }
  562.         else if(m_fPedal < 0.0f && m_lCurrentGear != REVERSE_GEAR)
  563.         {
  564.             m_fCurrentRPM = 1000.0f;
  565.             m_lCurrentGear = NEUTRAL_GEAR;
  566.             m_Velocity = m_Acceleration = TEVector(0.0f, 0.0f, 0.0f);
  567.         }
  568.     }
  569. }
  570. /*
  571. void FRCar::AlignToTerrain(TEEngine* pEngine)
  572. {
  573.     UInt16 usCount, usMaxY, usClip = 0;
  574.     TEMatrix3x3 XRot, YRot, ZRot;
  575.     TEVector aW[4], aInt[4], Dir, Mov;
  576.     bool abClip[4];
  577.  
  578.     XRot.XRotationMatrixDeg(-m_Rotation.m_fX);
  579.     YRot.YRotationMatrixDeg(-m_Rotation.m_fY);
  580.     ZRot.ZRotationMatrixDeg(-m_Rotation.m_fZ);
  581.  
  582.     Dir = TEVector(0, -m_CarSize.m_fZ, 0);
  583.     memset(&abClip, false, sizeof(bool)*4);
  584.     Mov = m_Right * m_CarSize.m_fX * 0.5f;
  585.  
  586.     aW[0] = m_Center;
  587.     aW[1] = aW[0] + Mov;                    // right front wheel
  588.     aW[0] -= Mov;                            // left front wheel
  589.  
  590.     aW[2] = m_Center + m_Forward * m_fRearAxis;
  591.     aW[3] = aW[2] + Mov;                    // right back wheel
  592.     aW[2] -= Mov;                            // left back wheel
  593.  
  594.     for(usCount = 0; usCount < 4; usCount++)
  595.     {
  596.         TEClipInfo Info;
  597.  
  598.         abClip[usCount] = pEngine->RayClipsInWorld(aW[usCount], Dir, Info, this);
  599.         aInt[usCount] = Info.Intersection;
  600.         
  601.         if(abClip[usCount])
  602.         {
  603.             usMaxY = usCount;
  604.             usClip++;
  605.         }
  606.     }
  607.  
  608.     for(usCount = 0; usCount < 4; usCount++)
  609.     {
  610.         if(abClip[usCount] && aInt[usCount].m_fY > aInt[usMaxY].m_fY)
  611.             usMaxY = usCount;
  612.     }
  613.  
  614.     if(usClip >= 3)
  615.     {
  616.         TEVector RX, RZ;
  617.  
  618.         switch(usMaxY){
  619.         case 0:
  620.             RX = aInt[0] - aInt[2];
  621.             RZ = aInt[1] - aInt[0];
  622.             break;
  623.         case 1:
  624.             RX = aInt[1] - aInt[3];
  625.             RZ = aInt[1] - aInt[0];
  626.             break;
  627.         case 2:
  628.             RX = aInt[0] - aInt[2];
  629.             RZ = aInt[3] - aInt[2];
  630.             break;
  631.         case 3:
  632.             RX = aInt[1] - aInt[3];
  633.             RZ = aInt[3] - aInt[2];
  634.             break;
  635.         default:
  636.             TEAssert(0);
  637.         };
  638.  
  639.  
  640.         RX = RX * (YRot * ZRot);
  641.         RZ = RZ * (XRot * YRot);
  642.  
  643.         RX.Normalize();
  644.         RZ.Normalize();
  645.  
  646.         if(RX.m_fY >= 0)
  647.             m_Rotation.m_fX = -TEACosDeg(RX.m_fZ);
  648.         else 
  649.             m_Rotation.m_fX = TEACosDeg(RX.m_fZ);
  650.  
  651.         if(RZ.m_fY >= 0)
  652.             m_Rotation.m_fZ = TEACosDeg(RZ.m_fX);
  653.         else 
  654.             m_Rotation.m_fZ = -TEACosDeg(RZ.m_fX);
  655.  
  656.         if(TEAbs(m_Rotation.m_fX) > 75.0f)
  657.             m_Rotation.m_fX = 0;
  658.         if(TEAbs(m_Rotation.m_fZ) > 75.0f)
  659.             m_Rotation.m_fZ = 0;
  660.     }
  661. }*/
  662.  
  663. void FRCar::UpdateEngine(UInt32 ulDeltaT, TEEngine* pEngine)
  664. {
  665.     Float fSpeed = m_Velocity.GetLength();
  666.     Float fTime = ulDeltaT / 1000.0f;
  667.  
  668.     if(m_lPowerUpInfluence == POWERUP_MINE)
  669.         m_fPedal = 0.0f;
  670.  
  671.     if(m_fPedal >= 0)
  672.     {
  673.         // driving forward
  674.         
  675.         if(m_lCurrentGear == NEUTRAL_GEAR && m_fPedal != 0)
  676.         {
  677.             m_lCurrentGear = FIRST_GEAR;
  678.         }
  679.  
  680.         if(m_lCurrentGear == REVERSE_GEAR)
  681.         {
  682.             if(m_fCurrentRPM > 1000)
  683.                 m_fCurrentRPM -= m_aGears[m_lCurrentGear].fRPMChange * fTime * m_fBrakeEfficiency;
  684.             
  685.             if(m_fCurrentRPM <= 1000)
  686.             {
  687.                 m_fCurrentRPM = 1000;
  688.                 m_lCurrentGear = NEUTRAL_GEAR;
  689.             }
  690.         }
  691.     }
  692.     else if(m_fPedal < 0)
  693.     {
  694.         if(fSpeed > 0.0001f && m_Velocity.DotProduct(m_Forward) / m_Velocity.GetLength() >= 0.99f)
  695.         {
  696.             // braking
  697.  
  698.             m_bBraking = true;
  699.  
  700.             if(m_fCurrentRPM > 1000)
  701.                 m_fCurrentRPM -= m_aGears[m_lCurrentGear].fRPMChange * fTime * m_fBrakeEfficiency;
  702.             
  703.             if(m_fCurrentRPM <= 1000)
  704.             {
  705.                 m_fCurrentRPM = 1000;
  706.                 m_lCurrentGear = REVERSE_GEAR;
  707.             }
  708.         }
  709.         else if(m_lCurrentGear != REVERSE_GEAR)
  710.         {
  711.             m_fCurrentRPM = 1000;
  712.             m_lCurrentGear = REVERSE_GEAR;
  713.         }
  714.     }
  715.  
  716.     if(!m_bBraking)
  717.     {
  718.         if(m_lCurrentGear != NEUTRAL_GEAR)
  719.         {
  720.             if(m_fCurrentRPM < m_fMaxRPM)
  721.                 m_fCurrentRPM += m_aGears[m_lCurrentGear].fRPMChange * TEAbs(m_fPedal) * fTime;
  722.             if(m_fPedal == 0)
  723.                 m_fCurrentRPM -= m_aGears[m_lCurrentGear].fRPMChange * fTime * 2.0f;
  724.         }
  725.     }
  726.  
  727.     // Shifting
  728.     if(m_lCurrentGear > REVERSE_GEAR)
  729.     {
  730.         if(m_fCurrentRPM >= m_fMaxRPM && m_lCurrentGear < (Int32)(m_ulNumGears - 1))
  731.         {
  732.             m_fCurrentRPM -= 1000;
  733.             m_lCurrentGear++;
  734.         }
  735.         if(m_fCurrentRPM < m_fMaxRPM * 0.5f && m_lCurrentGear > FIRST_GEAR)
  736.         {
  737.             m_fCurrentRPM += 1000;
  738.             m_lCurrentGear--;
  739.         }
  740.     }
  741.  
  742.     if(m_lPowerUpInfluence == POWERUP_MINE)
  743.         m_fCurrentRPM -= ulDeltaT * 5;
  744.  
  745.     if(m_fCurrentRPM < 1000)
  746.         m_fCurrentRPM = 1000;
  747.  
  748.     if(m_lCurrentGear != NEUTRAL_GEAR)
  749.     {
  750.         TEVector Tmp;
  751.  
  752.         Tmp =  m_Forward * (m_aGears[m_lCurrentGear].fRPMTrans * m_fCurrentRPM / m_fMaxRPM);
  753.  
  754.         if(m_bHandbrake)
  755.             Tmp = Tmp * 0.5f;
  756.         
  757.         m_Acceleration.m_fX = (Tmp.m_fX - m_Velocity.m_fX) * (1000 / (Float) ulDeltaT);
  758.         m_Acceleration.m_fZ = (Tmp.m_fZ - m_Velocity.m_fZ) * (1000 / (Float) ulDeltaT);
  759.     }
  760.  
  761.     if(m_fPedal == 0 && m_fCurrentRPM <= 1000 && m_lCurrentGear == FIRST_GEAR)
  762.     {
  763.         m_fCurrentRPM = 1000;
  764.         m_lCurrentGear = NEUTRAL_GEAR;
  765.     }
  766. }
  767.  
  768. void FRCar::UpdateVectors(void)
  769. {
  770.     TEOBoundingBox* pBox = (TEOBoundingBox*) m_pBoundingVolume;
  771.     TEPlane* pPlanes = pBox->GetPlanes();
  772.  
  773.     m_Forward = pPlanes[1].m_Normal;
  774.     m_Up = pPlanes[2].m_Normal;
  775.     m_Right = pPlanes[5].m_Normal;
  776. }
  777.  
  778. void FRCar::Reset(TEVector &rCenter, TEVector &rNormal)
  779. {
  780.     TETimer* pTimer = TETimer::GetTimer();
  781.     UInt32 ulTime = pTimer->GetTime();
  782.  
  783.     if(ulTime - m_ulLastReset < 3000)
  784.         return;
  785.  
  786.     TEOBoundingBox* pBox = (TEOBoundingBox*) m_pBoundingVolume;
  787.     TEAABoundingBox BBox;
  788.     TEVector Min, Max;    
  789.     Float fAngle = TEACosDeg(-rNormal.m_fZ);
  790.  
  791.     if(rNormal.m_fX > 0)
  792.         fAngle = -fAngle;
  793.  
  794.     m_Rotation = TEVector(0, fAngle, 0);
  795.     m_Center.m_fX = rCenter.m_fX;
  796.     m_Center.m_fZ = rCenter.m_fZ;
  797.     m_Velocity = m_Acceleration = TEVector(0,0,0);
  798.     m_lCurrentGear = NEUTRAL_GEAR;
  799.     m_fCurrentRPM = 1000;
  800.     
  801.     BBox = m_pModelRef->GetModelBBox();
  802.     BBox.GetData(Min, Max);
  803.     pBox->SetData(m_Center, Min, Max, m_Rotation);
  804.  
  805.     m_ulLastReset = ulTime;
  806.  
  807.     UpdateVectors();
  808.  
  809.     m_Visibility = BLINKING;
  810. }
  811.  
  812. void FRCar::CreateTyreDecals(UInt32 ulDeltaT, TEEngine* pEngine)
  813. {
  814.     TEVector Mov, T1, T2;
  815.     Float fDiff;
  816.     Mov = m_Right * (m_CarSize.m_fX * 0.5f - m_fWheelMov);
  817.  
  818.     T1 = m_OldCenter + m_Forward * m_fRearAxis;
  819.     T1.m_fY = 0.0f;
  820.     T2 = T1 + Mov;            // right back wheel
  821.     T1 = T1 - Mov;            // left back wheel
  822.     fDiff = m_Velocity.GetLength() * (ulDeltaT / 1000.0f);
  823.  
  824.     if(m_pDecalLeft == NULL || m_fDecalLengthLeft > MAX_TYRE_DECAL_LENGTH ||
  825.         m_DecalForward != m_Forward)
  826.     {
  827.         m_DecalStartLeft = T1;
  828.         m_fDecalLengthLeft = fDiff;
  829.         m_pDecalLeft = new FRCarDecal(m_DecalStartLeft, m_Forward, m_fDecalLengthLeft, m_fWheelWidth);
  830.         pEngine->AddDecal(m_pDecalLeft);
  831.     }
  832.     else
  833.     {
  834.         m_fDecalLengthLeft += fDiff;
  835.         m_pDecalLeft->SetData(m_DecalStartLeft, m_Forward, m_fDecalLengthLeft, m_fWheelWidth);
  836.     }
  837.  
  838.  
  839.     if(m_pDecalRight == NULL ||    m_fDecalLengthRight > MAX_TYRE_DECAL_LENGTH ||
  840.         m_DecalForward != m_Forward)
  841.     {
  842.         m_DecalStartRight = T2;
  843.         m_fDecalLengthRight = fDiff;
  844.         m_pDecalRight = new FRCarDecal(m_DecalStartRight, m_Forward, m_fDecalLengthRight, m_fWheelWidth);
  845.         pEngine->AddDecal(m_pDecalRight);
  846.     }
  847.     else
  848.     {
  849.         m_fDecalLengthRight += fDiff;
  850.         m_pDecalRight->SetData(m_DecalStartRight, m_Forward, m_fDecalLengthRight, m_fWheelWidth);
  851.     }
  852.  
  853.     m_DecalForward = m_Forward;
  854. }
  855.